using System;
using System.Reflection;
using System.Collections.Generic;

using Open.Data.Persistence;
using Open.Data.Persistence.SqlServer;

namespace Open.Data.Persistence.Testing
{
    //Returns settings depending on calling .dll. 
    sealed public class Singleton
    {
        //Singleton instance
        public static readonly Singleton Instance = new Singleton();

        //Property variables
        private static SqlContext _context;

        //Constructors
        private Singleton()
        {
            
        }

        //Methods
        public SqlContext GetContext()
        {
            if (_context == null) _context = CreateContext();

            _context.Prefix = "Open.Data.Persistence"; //reset in case changed by deployment tests
            return _context;
        }

        public SqlDeployment CreateDeployment()
        {
            return new SqlDeployment();
        }

        private SqlContext CreateContext()
        {
            SqlContext context = new SqlContext("Default");
            SqlDeployment deployment = new SqlDeployment(context);

            //Generate a random database name
            //For better validation tests, keep the same name
            string database = "db" + DateTime.Now.ToString().Replace("/", "").Replace(".", "").Replace(" ", "").Replace(":", "");
            deployment.CreateDatabase(database);
            
            context.Database = database;

            //Remove from front of name
            context.Prefix = "Open.Data.Persistence";

            //Validate the assembly against the database
            deployment.DeploymentType = Open.Data.Persistence.DeploymentType.Deploy;
            deployment.DeploymentMode = Open.Data.Persistence.DeploymentMode.Update;
            deployment.PreDeployType += new Open.Data.Persistence.PreDeployTypeHandler(deployment_PreDeployType);
            deployment.Deploy(System.Reflection.Assembly.GetExecutingAssembly());

            return context;
        }

        //Only deploy types that are authorised
        private void deployment_PreDeployType(object sender, Open.Data.Persistence.PreDeployTypeEventArgs e)
        {
            if (e.Type.FullName.Contains("Step") && e.Type.FullName.Contains("Entity")) e.Cancel = true;
        }
    }
}